package w

import (
	"encoding/json"
	"errors"
	"fmt"
	"gitee.com/snxamdf/wui/util"
	"strconv"
)

type WMap map[string]interface{}

const key = "value"

func NewMap() *WMap {
	m := &WMap{}
	return m
}

func ConvertByMap(i map[string]interface{}) WMap {
	m := WMap{}
	for k, v := range i {
		m.Put(k, v)
	}
	return m
}

func ConvertByJSON(jsonString string) (*WMap, error) {
	if jsonString != "" {
		tmp := &WMap{}
		if err := json.Unmarshal([]byte(jsonString), tmp); err != nil {
			return nil, err
		}
		return tmp, nil
	} else {
		return nil, errors.New("传入数据为空")
	}
}

func ToMap(data interface{}) *WMap {
	switch data.(type) {
	case map[string]interface{}:
		var tmp = data.(map[string]interface{})
		var c = ConvertByMap(tmp)
		return &c
	case *WMap:
		return data.(*WMap)
	case WMap:
		var tmp = data.(WMap)
		return &tmp
	case string:
		r, _ := ConvertByJSON(data.(string))
		return r
	}
	return nil
}

func (m WMap) Size() int {
	return len(m)
}

func (m WMap) ContainsKey(key string) bool {
	var _, ok = m[key]
	return ok
}

func (m WMap) Get(key string) interface{} {
	return m[key]
}

func (m WMap) Put(key string, value interface{}) WMap {
	m[key] = value
	return m
}

func (m WMap) PutValue(value interface{}) WMap {
	m[key] = value
	return m
}

func (m WMap) GetString(key string) string {
	if v, ok := m[key]; ok {
		return fmt.Sprintf("%v", v)
	} else {
		return ""
	}
}

func (m WMap) GetInt(key string) int {
	if v, ok := m[key]; ok {
		return util.ParseInt(v)
	} else {
		return 0
	}
}

func (m WMap) GetFloat64(key string) float64 {
	if v, ok := m[key]; ok {
		r := util.ParseString(v)
		if s, err := strconv.ParseFloat(r, 64); err != nil {
			return 0
		} else {
			return s
		}
	} else {
		return 0
	}
}

func (m WMap) GetFloat32(key string) float32 {
	if v, ok := m[key]; ok {
		r := util.ParseString(v)
		if s, err := strconv.ParseFloat(r, 32); err != nil {
			return 0
		} else {
			return float32(s)
		}
	} else {
		return 0
	}
}

func (m WMap) GetBool(key string) bool {
	if v, ok := m[key]; ok {
		r := util.ParseString(v)
		if r == "true" {
			return true
		}
	}
	return false
}

func (m WMap) Object() interface{} {
	if v, ok := m[key]; ok {
		return v
	} else {
		return nil
	}
}

func (m WMap) String() string {
	return util.ParseString(m[key])
}

func (m WMap) Int() int {
	return m.GetInt(key)
}

func (m WMap) Int32() int32 {
	return int32(m.Int())
}

func (m WMap) Int64() int64 {
	return int64(m.Int())
}

func (m WMap) Bool() bool {
	return m.GetBool(key)
}

func (m WMap) Float32() float32 {
	return m.GetFloat32(key)
}

func (m WMap) Float64() float64 {
	return m.GetFloat64(key)
}

func (m WMap) Bytes() []byte {
	if v, ok := m[key]; ok {
		r := util.ParseString(v)
		return []byte(r)
	} else {
		return nil
	}
}

func (m WMap) GetMap(key string) WMap {
	val := m[key]
	switch val.(type) {
	case map[string]interface{}:
		return val.(map[string]interface{})
	case string:
		return WMap{
			key: val,
		}
	}
	return nil
}

func (m WMap) GetArrayMap(key string) []WMap {
	val := m[key]
	switch val.(type) {
	case []interface{}:
		r := val.([]interface{})
		var rm []WMap
		for _, v := range r {
			rm = append(rm, v.(map[string]interface{}))
		}
		m.Put(key, rm)
		return rm
	}
	return nil
}

func (m WMap) ToJSON() (r []byte, err error) {
	r, err = util.ToJson(m)
	return r, err
}

func (m WMap) ToString() string {
	r, _ := m.ToJSON()
	return string(r)
}

func (m WMap) Type(key string) string {
	//reflect.TypeOf(m[key])
	switch m[key].(type) {
	case map[string]interface{}:
		return "map"
	case string:
		return "string"
	case []interface{}:
		return "array"
	case int:
	case int32:
	case int64:
		return "int"
	case float64:
	case float32:
		return "float"
	case bool:
		return "bool"

	}
	return ""
}
